﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ThresholdAssistant.Autofac;
using ThresholdAssistant.DataContract.Result;
using ThresholdAssistant.NLogSdk;
using ThresholdAssistant.Tools.Extensions;
using ThresholdAssistant.WebAPI.Models;
using ThresholdAssistant.WebAPI.Models.Constants;
using ThresholdAssistant.WebAPI.Models.Enums;
using ThresholdAssistant.WebAPI.Repository;

namespace ThresholdAssistant.WebAPI.Service
{
    /// <summary>
    /// 用户服务
    /// </summary>
    public class MemberService : BaseService, IBaseAutofac
    {
        /// <summary>
        /// 用户仓储
        /// </summary>
        public MemberRepository MemberRepository { get; set; }

        /// <summary>
        /// 创建二维码记录仓储
        /// </summary>
        public CreateQrcodeRecordRepository CreateQrcodeRecordRepository { get; set; }
        /// <summary>
        /// 参数仓储
        /// </summary>
        public ConfigRepository ConfigRepository { get; set; }

        /// <summary>
        /// 微信授权登录
        /// </summary>
        /// <param name="jsCode"></param>
        /// <returns></returns>
        public async Task<ContractResult<WechatLoginData>> WechatLoginAsync(string jsCode)
        {
            var result = new ContractResult<WechatLoginData>();
            try
            {
                //授权登录
                var response = await HttpHelper.WechatAuthLoginAsync(HttpClient, jsCode);
                if (response != null && response.ErrCode != 0)
                {
                    return result.SetError("-1", response.ErrMsg);
                }
                var openId = response.OpenId;
                var memberInfo = await MemberRepository.GetInfoByOpenIdAsync(openId);
                if (memberInfo == null || memberInfo?.Id == 0)
                {
                    memberInfo = new Member
                    {
                        WxOpenId = openId,
                        NickName = $"wx_{openId.Substring(openId.Length - 6, 6)}",//初始化一下昵称
                        Sex = 0,
                        Phone = "",
                        Profile = "",
                        GroupId = 0,
                        IsMaster = 0,
                        CreateTime = DateTime.Now,
                        UpdateTime = DateTime.Now,
                        Remark = ""
                    };
                    memberInfo.Id = await MemberRepository.AddAsync(memberInfo);

                    //参数初始化
                    if (memberInfo.Id > 0)
                    {
                        await InitConfig(memberInfo.Id);
                    }
                }

                var token = GetToken(memberInfo.Id);
                var key = RedisConstant.UserTokenKey(token);
                await _cache.SetNxAsync(key, memberInfo, 60 * 60 * 24);
                return result.SetSuceccful(new WechatLoginData
                {
                    UserId = memberInfo.Id,
                    Token = token,
                    OpenId = openId,
                    Phone = memberInfo.Phone,
                    GroupId = memberInfo.GroupId,
                    Profile = memberInfo.Profile,
                    InviteCode = (memberInfo.IsMaster == 1 || memberInfo.GroupId == 0) ? openId.Substring(openId.Length - 6, 6) : GetInviteCode(memberInfo.GroupId)
                });
            }
            catch (Exception ex)
            {
                NLogUtil.Error($"【授权登录】授权失败,请求CODE:{jsCode},失败原因{ex}");
            }
            return result.SetError(ErrorResultEnum.RequestApiFail);
        }



        /// <summary>
        /// 检测token是否可用
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task<ContractResult<long>> CheckTokenAsync(string token)
        {
            var result = new ContractResult<long>();
            try
            {
                var key = RedisConstant.UserTokenKey(token);
                var member = await _cache.GetAsync<Member>(key);
                //var userIdStr = await _cache.StringGetAsync(key);

                if (member == null || member.Id == 0)
                {
                    return result.SetError("-1", "token失效");
                }
                return result.SetSuceccful(member.Id);
            }
            catch (Exception ex)
            {
                NLogUtil.Error($"CheckTokenAsync:{ex}");
                return result.SetError("-1", "token失效");
            }
        }

        /// <summary>
        /// 获取Token
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        private string GetToken(long userId)
        {
            return $"{userId}{Guid.NewGuid()}".ToSerialNo();
        }

        /// <summary>
        /// 创建群组二维码
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ContractResult<InviteData>> CreateGroupQrCodeAsync(CreateGroupQrCodeParam param)
        {
            var result = new ContractResult<InviteData>();
            var userInfo = await MemberRepository.GetInfoAsync(param.MemberId);
            if (userInfo == null)
            {
                return result.SetError(ErrorResultEnum.UserNotExists);
            }
            //if (userInfo.IsMaster == 1)
            //{
            //    return result.SetError(ErrorResultEnum.UserNotExists);
            //}
            //if (string.IsNullOrWhiteSpace(userInfo.WxOpenId))
            //{
            //    return result.SetError(ErrorResultEnum.WxOpenIdIsNull);
            //}
            var recordInfo = await CreateQrcodeRecordRepository.GetInfoByMemberIdAsync(userInfo.Id);
            if (recordInfo != null)
            {
                result.Data = new InviteData
                {
                    InviteCode = recordInfo.Data,
                    QrCodeUrl = recordInfo.LocalFilePath
                };
                // todo 解析地址为url
                return result.SetSuceccful();
            }
            //var content = $"{AppSettingConstant.AppletGroupUrl}?share_open_id={userInfo.WxOpenId}";
            var content = userInfo.WxOpenId.Substring(userInfo.WxOpenId.Length - 6, 6);
            var path = "";// userInfo.WxOpenId.ToQrCode(AppSettingConstant.ImgSavePath);
            var createQrcodeRecord = new CreateQrcodeRecord
            {
                MemberId = param.MemberId,
                LocalFilePath = path,
                Data = content,
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now,
                Remark = ""
            };
            // todo 解析地址为url
            // opt 这里可以优化一下把图片存七牛云
            result.Data = new InviteData
            {
                InviteCode = content,
                QrCodeUrl = path
            };
            return result.SetSuceccful();
        }

        /// <summary>
        /// 加入群组
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ContractResult<long>> JoinGroupAsync(JoinGroupParam param)
        {
            var result = new ContractResult<long>();

            var shareUserInfo = await MemberRepository.GetInfoByInviteCodeAsync(param.InviteCode);
            if (shareUserInfo == null)
            {
                return result.SetError(ErrorResultEnum.InviteCodeInvalid);
            }

            var joinUserInfo = await MemberRepository.GetInfoByOpenIdAsync(param.JoinOpenId);
            if (joinUserInfo == null)
            {
                return result.SetError(ErrorResultEnum.InviteCodeInvalid);
            }
            if (joinUserInfo.IsMaster == 1)
            {
                return result.SetError(ErrorResultEnum.IsMaster);
            }
            //判断分组id
            var groupId = shareUserInfo.GroupId > 0 ? shareUserInfo.GroupId : shareUserInfo.Id;
            if (joinUserInfo.GroupId > 0 && joinUserInfo.GroupId != groupId)
            {
                return result.SetError(ErrorResultEnum.JoinOtherGroup);
            }
            //在群直接返回
            if (joinUserInfo.GroupId == groupId)
            {
                return result.SetSuceccful();
            }

            var groupUserCount = await MemberRepository.GetMemberCountByGroupIdAsync(groupId);
            if (groupUserCount >= AppSettingConstant.GroupMemberLimitCount)
            {
                return result.SetError(ErrorResultEnum.GroupFullMember);
            }
            if (shareUserInfo.IsMaster == 0)
            {
                //设置群主
                await MemberRepository.UpdateIsMasterAsync(shareUserInfo.Id, 1);
            }

            var list = new List<long> { joinUserInfo.Id };
            if (shareUserInfo.GroupId == 0)
            {
                list.Add(shareUserInfo.Id);
            }
            //设置群ID
            await MemberRepository.UpdateGroupIdAsync(list, groupId);
            return result.SetSuceccful(groupId);
        }

        /// <summary>
        /// 退出群组
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ContractResult> WithdrawGroupAsync(WithdrawGroupParam param)
        {
            var result = new ContractResult();
            var joinUserInfo = await MemberRepository.GetInfoAsync(param.MemberId);
            if (joinUserInfo == null)
            {
                return result.SetError(ErrorResultEnum.UserNotExists);
            }
            if (param.GroupId != joinUserInfo.GroupId)
            {
                return result.SetError(ErrorResultEnum.NotInGroup);
            }

            var memberIdList = new List<long> { joinUserInfo.Id };
            if (joinUserInfo.IsMaster == 1)
            {
                await MemberRepository.UpdateIsMasterAsync(joinUserInfo.Id, 0);
                var _memberIdList = await MemberRepository.GetMemberIdListByGroupIdAsync(param.GroupId);
                if (_memberIdList?.Count() > 0)
                {
                    memberIdList = _memberIdList.ToList();
                }
            }

            await MemberRepository.UpdateGroupIdAsync(memberIdList, 0);

            return result.SetSuceccful();
        }

        /// <summary>
        /// 群内踢人
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ContractResult> TickGroupAsync(TickGroupParam param)
        {
            var result = new ContractResult();
            var masterInfo = await MemberRepository.GetInfoAsync(param.MasterId);
            if (masterInfo == null)
            {
                return result.SetError(ErrorResultEnum.UserNotExists);
            }
            if (param.GroupId != masterInfo.GroupId)
            {
                return result.SetError(ErrorResultEnum.NotInGroup);
            }
            if (masterInfo.IsMaster != 1)
            {
                return result.SetError(ErrorResultEnum.NotGroupMaster);
            }
            var memberInfo = await MemberRepository.GetInfoAsync(param.MemberId);
            if (memberInfo == null)
            {
                return result.SetError(ErrorResultEnum.UserNotExists);
            }
            if (param.GroupId != memberInfo.GroupId)
            {
                return result.SetError(ErrorResultEnum.NotInGroup);
            }

            var memberIdList = new List<long> { memberInfo.Id };

            await MemberRepository.UpdateGroupIdAsync(memberIdList, 0);

            return result.SetSuceccful();
        }

        /// <summary>
        /// 修改微信相关信息
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ContractResult> ModifyWeChatInfoAsync(ModifyWeChatInfoParam param)
        {
            var result = new ContractResult();
            var memberInfo = await MemberRepository.GetInfoByOpenIdAsync(param.OpenId);
            if (memberInfo == null)
            {
                await MemberRepository.AddAsync(new Member
                {
                    WxOpenId = param.OpenId,
                    NickName = param.NickName,
                    Sex = 0,
                    Phone = param.Phone,
                    Profile = "",
                    GroupId = 0,
                    IsMaster = 0,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    Remark = ""
                });
            }
            else
            {
                var needModify = false;
                if (!string.IsNullOrWhiteSpace(param.NickName))
                {
                    memberInfo.NickName = param.NickName;
                    needModify = true;
                }
                //if (memberInfo.Sex != param.Sex)
                //{
                //    memberInfo.Sex = param.Sex;
                //    needModify = true;
                //}
                if (!string.IsNullOrWhiteSpace(param.Phone))
                {
                    memberInfo.Phone = param.Phone;
                    needModify = true;
                }
                if (needModify)
                {
                    memberInfo.UpdateTime = DateTime.Now;
                    await MemberRepository.UpdateWxInfoAsync(memberInfo);
                }
            }

            return result.SetSuceccful();
        }


        /// <summary>
        /// 修改手机号码
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ContractResult> ModifyPhoneAsync(ModifyPhoneParam param)
        {
            var result = new ContractResult();
            var memberInfo = await MemberRepository.GetInfoAsync(param.Id);
            if (memberInfo == null)
            {
                return result.SetError(ErrorResultEnum.UserNotExists);
            }
            else
            {
                await MemberRepository.UpdatePhoneAsync(param.Id, param.Phone);
            }
            return result.SetSuceccful();
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ContractResult<MemberData>> GetInfoAsync(GetInfoParam param)
        {
            var result = new ContractResult<MemberData>();
            var memberInfo = new Member();
            if (param.Id > 0)
            {
                memberInfo = await MemberRepository.GetInfoAsync(param.Id);
            }
            else
            {
                memberInfo = await MemberRepository.GetInfoByOpenIdAsync(param.OpenId);
            }
            if (memberInfo == null)
            {
                return result.SetError(ErrorResultEnum.UserNotExists);
            }
            result.Data = new MemberData
            {
                Id = memberInfo.Id,
                OpenId = memberInfo.WxOpenId,
                NickName = memberInfo.NickName,
                Sex = memberInfo.Sex == 0 ? "未知" : memberInfo.Sex == 1 ? "男" : "女",
                GroupId = memberInfo.GroupId,
                IsMaster = memberInfo.IsMaster == 1,
                Profile = memberInfo.Profile,
                Phone = memberInfo.Phone,
            };
            return result.SetSuceccful();
        }

        /// <summary>
        /// 获取群成员列表
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public async Task<ContractResult<IEnumerable<MemberData>>> GetGroupMemberListAsync(GetGroupMemberListParam param)
        {
            var reult = new ContractResult<IEnumerable<MemberData>>();
            var memberList = await MemberRepository.GetMemberListByGroupIdAsync(param.GroupId);
            reult.Data = memberList.Select(x => new MemberData
            {
                Id = x.Id,
                OpenId = x.WxOpenId,
                NickName = x.NickName,
                Sex = x.Sex == 0 ? "未知" : x.Sex == 1 ? "男" : "女",
                GroupId = x.GroupId,
                IsMaster = x.IsMaster == 1,
                Profile = x.Profile,
                Phone = x.Phone
            });
            return reult.SetSuceccful();
        }

        /// <summary>
        /// 组数据初始化
        /// </summary>
        /// <param name="groupId"></param>
        /// <returns></returns>
        private async Task InitConfig(long groupId)
        {
            var records = await ConfigRepository.GetListByGroupIdAsync(groupId);
            if (records == null || records?.Any() == false)
            {
                var list = new List<Config>();
                list.Add(new Config() { GroupId = groupId, ConfigType = ConfigTypeEnum.IsWeChatNotice, ConfigName = "微信通知", ConfigValue = "1", ControlType = "switch", ControlIcon = "notification" });
                list.Add(new Config() { GroupId = groupId, ConfigType = ConfigTypeEnum.IsMobileSMS, ConfigName = "短信通知", ConfigValue = "0", ControlType = "switch", ControlIcon = "sound" });
                list.Add(new Config() { GroupId = groupId, ConfigType = ConfigTypeEnum.DataClearType, ConfigName = "数据自动清空", ConfigValue = "0", Remark = "不清空", ControlType = "select", ControlIcon = "chart" });
                list.Add(new Config() { GroupId = groupId, ConfigType = ConfigTypeEnum.ClearUp, ConfigName = "立即清空", ConfigValue = "0", ControlType = "switch", ControlIcon = "app" });
                await ConfigRepository.AddListAsync(list);
            }
        }
        private string GetInviteCode(long groupId)
        {
            var openId = MemberRepository.GetOpenId(groupId);
            return openId.Substring(openId.Length - 6, 6);
        }

    }
}